package com.mspbots.rule.exceptions.cw;

import cn.hutool.core.util.StrUtil;
import com.mspbots.cw.request.TenantDTO;
import com.mspbots.cw.request.TenantTicketDTO;
import com.mspbots.cw.request.TenantTimeEntryDTO;
import lombok.extern.slf4j.Slf4j;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

/**
 * com.mspbots.rule.exceptions.timeentry.NotIncludingWords
 *
 * @author Jun Zhou
 * @date 12:32 2019/7/1
 **/
@Slf4j
@Rule(name = "NoNextStep", description = "Time log entry has no “xxx” in it.")
public class NoNextStep extends CwBaseRule implements IcwBaseRule {

    private static List<String> TICKET_STATUS = Arrays.asList(
            "Completed (Emails Contact & CC)",
            "Canceled No Response (Emails Contact & CC)",
            "Client Canceled (Emails Contact & CC)",
            "Canceled (No Email)",
            "Closed (Canceled)",
            "Closed (MGR)",
            "Closed (FINAL)"
    );

    @Condition
    @Override
    public boolean condition(@Fact(FACT) TenantTimeEntryDTO entry) {
        try {
            if (!setUserMapping(entry.getTenantUserId()) || super.checkMessage(entry)) {
                return false;
            }

            if ("travel".equalsIgnoreCase(entry.getExtend().findPath("workType").get("name").asText())) {
                return false;
            }

            Iterator<String> iterator = this.tenantRuleDTO.getRuleParams().fieldNames();
            boolean contains = false;
            while (iterator.hasNext()) {
                String fieldName = iterator.next();
                contains = contains || entry.getDescription().toLowerCase().contains(this.tenantRuleDTO.getRuleParams().get(fieldName).asText().toLowerCase());
            }

            if (!contains && !ObjectUtils.isEmpty(entry.getExtend().get("chargeToId"))) {
                Map<String, Object> ticketsParams = Map.of("tenantId", entry.getTenantId(),
                        "cwId", entry.getExtend().get("chargeToId"));
                TenantTicketDTO tenantTicketDTO = this.coreClient.get("/tickets/detail", ticketsParams, TenantTicketDTO.class).block();
                if (tenantTicketDTO == null || StringUtils.isEmpty(tenantTicketDTO.getStatus())) {
                    log.info("tenantTicketDTO_is null or status is null {}", entry.getId());
                    return false;
                }

                Long count = TICKET_STATUS.parallelStream().filter(item -> tenantTicketDTO.getStatus().toLowerCase().contains(item.toLowerCase())).count();

                if (count > 0 || tenantTicketDTO.getStatus().toLowerCase().contains("completed")) {
                    log.info("timeEntry_{} in ticket condition", entry.getId());
                    return false;
                }

                TenantDTO tenant = this.coreClient.get("/tenant/name/itsasap", ticketsParams, TenantDTO.class).block();
                //ITS condition
                if (tenantTicketDTO != null && tenantTicketDTO.getTenantId() == tenant.getId()
                        && tenantTicketDTO.getExtend().findPath("type") != null
                        && tenantTicketDTO.getExtend().findPath("type").get("name") != null) {
                    if (("admin / break".equalsIgnoreCase(tenantTicketDTO.getExtend().findPath("type").get("name").asText())
                            || "Low survey score".equalsIgnoreCase(tenantTicketDTO.getExtend().findPath("type").get("name").asText()))) {
                        log.info("timeEntry_{} in ITS condition", entry.getId());
                        return false;
                    }

                }
                log.info("next step {} {} {} ", tenantTicketDTO.getCwId(), tenantTicketDTO.getStatus(), tenantTicketDTO.getSyncTime());
            }
            return !contains;
        } catch (Exception e) {
            log.error("NoNextStep rule execute error : {} : {}", e.getMessage(), entry);
            e.printStackTrace();
        }
        return false;
    }

    @Action
    @Override
    public void action(@Fact(FACT) TenantTimeEntryDTO entry) {
        messages.setTimeEntryId(entry.getCwTid());
        Map params = new HashMap(16);
        params.put("TimeEntryLink", formatCwLink(entry.getCwTid()));
        String message = getMessage(entry);
        if (message != null) {
            String msg = StrUtil.format(message, params);
            messages.setMessage(msg);
            insertMessage();
        }


    }


}
